package com.modifymetrodemo.async;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;

import androidx.annotation.Nullable;

import com.facebook.infer.annotation.Assertions;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactDelegate;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactRootView;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactMarker;
import com.facebook.react.bridge.ReactMarkerConstants;
import com.facebook.react.modules.core.PermissionListener;
import com.modifymetrodemo.beans.ReactNativeBusinessInfo;
import com.modifymetrodemo.utils.TimeRecordUtils;

public class MyReactActivityDelegate {

    private @Nullable
    Activity mActivity;

    private @Nullable
    PermissionListener mPermissionListener;
    private @Nullable
    Callback mPermissionsCallback;
    private ReactDelegate mReactDelegate;

    private static boolean isCommonBundleLoadFinished = false;

    private ReactNativeBusinessInfo mBusinessInfo;

    @Deprecated
    public MyReactActivityDelegate(Activity activity) {
        mActivity = activity;
        ReactMarker.addListener((name, tag, instanceKey) -> {
            Log.d("maji", "name: " + name.name() + " , tag: " + tag + ", instanceKey=" + instanceKey);
            if (name == ReactMarkerConstants.NATIVE_MODULE_INITIALIZE_END) {
                isCommonBundleLoadFinished = true;
            }
            if (name == ReactMarkerConstants.CONTENT_APPEARED) {
                TimeRecordUtils.setEndTime();
                TimeRecordUtils.printTimeInfo();
            }
        });
    }

    public MyReactActivityDelegate(ReactActivity activity) {
        mActivity = activity;
    }

    protected @Nullable
    Bundle getLaunchOptions() {
        return null;
    }

    protected ReactRootView createRootView() {
        return new ReactRootView(getContext());
    }

    /**
     * Get the {@link ReactNativeHost} used by this app. By default, assumes {@link
     * Activity#getApplication()} is an instance of {@link ReactApplication} and calls {@link
     * ReactApplication#getReactNativeHost()}. Override this method if your application class does not
     * implement {@code ReactApplication} or you simply have a different mechanism for storing a
     * {@code ReactNativeHost}, e.g. as a static field somewhere.
     */
    protected ReactNativeHost getReactNativeHost() {
        return ((ReactApplication) getPlainActivity().getApplication()).getReactNativeHost();
    }

    public ReactInstanceManager getReactInstanceManager() {
        return mReactDelegate.getReactInstanceManager();
    }

    private String getMainComponentName() {
        return mBusinessInfo != null ? mBusinessInfo.mainComponentName : "";
    }

    private String getBundleFilePath() {
        return mBusinessInfo != null ? mBusinessInfo.bundleFilePath : "";
    }

    protected void onCreateInParentActivity(Bundle savedInstanceState) {
            final ReactInstanceManager manager = getReactNativeHost().getReactInstanceManager();

        manager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
            @Override
            public void onReactContextInitialized(ReactContext context) {
                Log.d("maji", " 基础包加载完毕 ");
                manager.removeReactInstanceEventListener(this);
            }
        });
        getReactNativeHost().getReactInstanceManager().createReactContextInBackground();
    }

    protected void onCreateInChildActivity(Activity activity, Bundle savedInstanceState, ReactNativeBusinessInfo businessInfo) {
        mActivity = activity;
        mBusinessInfo = businessInfo;
        mReactDelegate =
                new ReactDelegate(
                        activity,
                        getReactNativeHost(),
                        getMainComponentName(), getLaunchOptions()) {
                    @Override
                    protected ReactRootView createRootView() {
                        return MyReactActivityDelegate.this.createRootView();
                    }
                };
        getReactInstanceManager().getCurrentReactContext().getCatalystInstance()
                .loadScriptFromAssets(
                        getContext().getAssets(),
                        getBundleFilePath(),
                        false
                );
        // 加载视图
        loadApp(getMainComponentName());
    }

    @Deprecated
    protected void onCreateInChildActivity2(Activity activity, Bundle savedInstanceState) {
        mActivity = activity;
        Handler handler = new Handler(Looper.myLooper());
        String mainComponentName = getMainComponentName();
        if (null == mReactDelegate) {
            mReactDelegate =
                    new ReactDelegate(
                            activity,
                            getReactNativeHost(),
                            mainComponentName,
                            getLaunchOptions()) {
                        @Override
                        protected ReactRootView createRootView() {
                            return MyReactActivityDelegate.this.createRootView();
                        }
                    };
        }
        if (!isCommonBundleLoadFinished) {
            handler.postDelayed(() -> {// 加载业务包
                onCreateInChildActivity2(activity, savedInstanceState);
            }, 10);
            Log.e("maji", "未准备好");
        } else {
            Log.d("maji", "准备好了)");
            getReactInstanceManager().getCurrentReactContext().getCatalystInstance()
                    .loadScriptFromAssets(
                            getContext().getAssets(),
                            getBundleFilePath(),
                            true
                    );
            loadApp(getMainComponentName());
        }
    }

    protected void onCreate(Bundle savedInstanceState, ReactNativeBusinessInfo businessInfo) {
        mBusinessInfo = businessInfo;
        String mainComponentName = getMainComponentName();
        mReactDelegate =
                new ReactDelegate(
                        getPlainActivity(), getReactNativeHost(), mainComponentName, getLaunchOptions()) {
                    @Override
                    protected ReactRootView createRootView() {
                        return MyReactActivityDelegate.this.createRootView();
                    }
                };

        checkAndLoadBusinessBundle();
        // checkAndLoadBusinessBundle2(mainComponentName);
        getReactNativeHost().getReactInstanceManager().createReactContextInBackground();
    }

    private void checkAndLoadBusinessBundle2(String mainComponentName) {
        final ReactInstanceManager manager = getReactNativeHost().getReactInstanceManager();
        manager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
            @Override
            public void onReactContextInitialized(ReactContext context) {
                Log.d("rndebug", " 基础包加载完毕 ");
                // 加载视图
                getReactInstanceManager().getCurrentReactContext().getCatalystInstance()
                        .loadScriptFromAssets(
                                getContext().getAssets(),
                                getBundleFilePath(), //"assets://diff.android.bundle",
                                false
                        );
                loadApp(getMainComponentName());
                manager.removeReactInstanceEventListener(this);
            }
        });
    }

    // Fixme
    Handler handler = new Handler(Looper.myLooper());

    private void checkAndLoadBusinessBundle() {
        Log.e("loadApp", "Bundle Path: " + getBundleFilePath());
        if (isCommonBundleLoadFinished) {
            getReactInstanceManager().getCurrentReactContext().getCatalystInstance()
                    .loadScriptFromAssets(
                            getContext().getAssets(),
                            getBundleFilePath(),
                            false
                    );
            loadApp(getMainComponentName());
        } else {
            // 加载业务包
            handler.postDelayed(this::checkAndLoadBusinessBundle, 10);
        }
    }

    protected void loadApp(String appKey) {
        if (TextUtils.isEmpty(appKey)) {
            Log.e("maji", "loadApp failed, as for appKey is empty.");
            return;
        }
        Log.d("maji", "loadApp: " + appKey);
        mReactDelegate.loadApp(appKey);
        getPlainActivity().setContentView(mReactDelegate.getReactRootView());
    }

    protected void onPause() {
        mReactDelegate.onHostPause();
    }

    protected void onResume() {
        mReactDelegate.onHostResume();

        if (mPermissionsCallback != null) {
            mPermissionsCallback.invoke();
            mPermissionsCallback = null;
        }
    }

    protected void onDestroy() {
        mReactDelegate.onHostDestroy();
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        mReactDelegate.onActivityResult(requestCode, resultCode, data, true);
    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (getReactNativeHost().hasInstance()
                && getReactNativeHost().getUseDeveloperSupport()
                && keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD) {
            event.startTracking();
            return true;
        }
        return false;
    }

    public boolean onKeyUp(int keyCode, KeyEvent event) {
        return mReactDelegate.shouldShowDevMenuOrReload(keyCode, event);
    }

    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
        if (getReactNativeHost().hasInstance()
                && getReactNativeHost().getUseDeveloperSupport()
                && keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD) {
            getReactNativeHost().getReactInstanceManager().showDevOptionsDialog();
            return true;
        }
        return false;
    }

    public boolean onBackPressed() {
        return mReactDelegate.onBackPressed();
    }

    public boolean onNewIntent(Intent intent) {
        if (getReactNativeHost().hasInstance()) {
            getReactNativeHost().getReactInstanceManager().onNewIntent(intent);
            return true;
        }
        return false;
    }

    public void onWindowFocusChanged(boolean hasFocus) {
        if (getReactNativeHost().hasInstance()) {
            getReactNativeHost().getReactInstanceManager().onWindowFocusChange(hasFocus);
        }
    }

    @TargetApi(Build.VERSION_CODES.M)
    public void requestPermissions(
            String[] permissions, int requestCode, PermissionListener listener) {
        mPermissionListener = listener;
        getPlainActivity().requestPermissions(permissions, requestCode);
    }

    public void onRequestPermissionsResult(
            final int requestCode, final String[] permissions, final int[] grantResults) {
        mPermissionsCallback =
                args -> {
                    if (mPermissionListener != null
                            && mPermissionListener.onRequestPermissionsResult(
                            requestCode, permissions, grantResults)) {
                        mPermissionListener = null;
                    }
                };
    }

    protected Context getContext() {
        return Assertions.assertNotNull(mActivity);
    }

    protected Activity getPlainActivity() {
        return ((Activity) getContext());
    }
}
